package basicx.oop.classx

/*-*- coding:utf-8 -*-
* @Author  : ygree 
* @Time    : 2021/7/6 14:51
* @Software : IntelliJ IDEA
*/
private class People {
    /**如果一个类只对另一个类有用，那么将其嵌入到该类中并使这两个类保持在一起是合
    乎逻辑的，可以使用嵌套类。
     */
    class Player {
        class Equipment(var name: String) {
            fun show() = println("Equipment:$name")
        }

        class Battle {}
    }
}

// 内部类
// 内部类使用 inner 关键字来表示。
// 内部类会带有一个对外部类的对象的引用，所以内部类可以访问外部类成员属性和成员函数。

class Outer {
    var v = "Outer成员属性"
    fun update(v: String) {
        this.v = v
    }

    /**嵌套内部类**/
    inner class Inner {
        fun foo() = v // 访问外部类成员
        fun innerTest() {
            var o = this@Outer // 获取外部类的成员变量
            println("->this@Outer ${o.v} ")
        }
    }
}

// 为了消除歧义，要访问来自外部作用域的 this，我们使用this@label，其中 @label 是一个 代指 this 来源的标签。
// 使用对象表达式来创建匿名内部类：
interface TestInterFace {
    fun test()
}

class Test {
    var v = "成员属性"
    fun setInterFace(test: TestInterFace) {
        test.test()
    }
}



private fun people() {
    People.Player.Battle()
    //java中之后static 类型的才可以直接 类名.类名.调用
    People.Player.Equipment("流星蝴蝶剑").show()
}

fun outer() {
//    内部类
    println("====outer======")
    val outer = Outer()
    val inner = outer.Inner()
    println("inner.foo ${inner.foo()}") //   1
    println("inner.innerTest ${inner.innerTest()}") //   1
    outer.update("aaaa")
    println("inner.foo ${inner.foo()}") //   1
    println("inner.innerTest ${inner.innerTest()}") //   1


//    匿名内部类
    var test = Test()
    /**
     * 采用对象表达式来创建接口对象，即匿名内部类的实例。
     */
    test.setInterFace(object : TestInterFace {
        override fun test() {
            println("对象表达式创建匿名内部类的实例")
        }
    })
}

fun main(args: Array<String>) {
    people()
    outer()
}

